﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Text;
using System.Threading.Tasks;
using Abp;
using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.AutoMapper;
using Abp.Configuration;
using Abp.Domain.Repositories;
using Abp.Extensions;
using System.Linq.Dynamic.Core;
using Abp.Linq.Extensions;

using KDS.Mes.Mes.JitAlcCodes.Dtos;
using KDS.Mes.Dto;
using KDS.Mes.Mes.Styles;
using KDS.Mes.Mes.Cartypes;
using KDS.Mes.Mes.AlcCodes;
using KDS.Mes.Mes.Lines;
using KDS.Mes.Mes.Storages;



namespace KDS.Mes.Mes.JitAlcCodes
{
    /// <summary>
    /// Jit生产ALCCode信息服务实现
    /// </summary>

    public class JitAlcCodeAppService : MesAppServiceBase, IJitAlcCodeAppService
    {
        private readonly IRepository<JitAlcCode, int> _jitAlcCodeRepository;
        private readonly IJitAlcCodeListExcelExporter _jitAlcCodeListExcelExporter;
        private readonly IRepository<Style, int> _styleRepository;
        private readonly IRepository<Cartype, int> _cartypeRepository;
        private readonly IRepository<AlcCode, int> _alcCodeRepository;
        private readonly IRepository<Line, int> _lineRepository;
        private readonly IRepository<Storage, int> _storageRepository;


        private readonly JitAlcCodeManage _jitAlcCodeManage;
        /// <summary>
        /// 构造方法
        /// </summary>
        public JitAlcCodeAppService(
            IRepository<JitAlcCode, int> jitAlcCodeRepository,
            JitAlcCodeManage jitAlcCodeManage, 
            IJitAlcCodeListExcelExporter jitAlcCodeListExcelExporter,
            IRepository<Style, int> styleRepository,
            IRepository<Cartype, int> cartypeRepository,
            IRepository<AlcCode, int> alcCodeRepository,
            IRepository<Line, int> lineRepository,
            IRepository<Storage, int> storageRepository
        )
        {
            _jitAlcCodeRepository = jitAlcCodeRepository;
            _jitAlcCodeManage = jitAlcCodeManage;
            _jitAlcCodeListExcelExporter = jitAlcCodeListExcelExporter;
            _alcCodeRepository = alcCodeRepository;
            _styleRepository = styleRepository;
            _cartypeRepository = cartypeRepository;
            _lineRepository = lineRepository;
            _storageRepository = storageRepository;
        }


        #region 实体的自定义扩展方法
        private IQueryable<JitAlcCode> _jitAlcCodeRepositoryAsNoTrack => _jitAlcCodeRepository.GetAll().AsNoTracking();


        #endregion


        #region Jit生产ALCCode信息管理

        public PagedResultDto<JitAlcCodeListDto> GetPagedJitAlcCodes(GetJitAlcCodeInput input)
        {
            ////初步过滤
            //var query = _jitAlcCodeRepository.GetAll();
            ////排序
            //query = query.OrderBy(x => x.Id);
            ////获取总数
            //var tasksCount = query.Count();
            ////默认的分页方式
            ////var taskList = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
            ////ABP提供了扩展方法PageBy分页方式
            //var taskList = query.PageBy(input).ToList();
            //return new PagedResultDto<JitAlcCodeListDto>(tasksCount, taskList.MapTo<List<JitAlcCodeListDto>>());




            //初步过滤
            //var query = _alcCodeRepository.GetAll();
            //初步过滤
            var query = from jalc in _jitAlcCodeRepository.GetAll()
                        join alc in _alcCodeRepository.GetAll().WhereIf(!input.AlcCodeId.IsNullOrEmpty(), u => u.Id.ToString() == input.AlcCodeId) on jalc.AlcCodeId equals alc.Id
                        join st in _styleRepository.GetAll().WhereIf(!input.StyleId.IsNullOrEmpty(), u => u.Id.ToString() == input.StyleId) on alc.StyleId equals st.Id
                        join ct in _cartypeRepository.GetAll().WhereIf(!input.CartypeId.IsNullOrEmpty(), u => u.Id.ToString() == input.CartypeId) on st.CartypeId equals ct.Id
                        join ln in _lineRepository.GetAll().WhereIf(!input.LineId.IsNullOrEmpty(), u => u.Id.ToString() == input.LineId) on jalc.LineId equals ln.Id
                        join sg in _storageRepository.GetAll().WhereIf(!input.StorageId.IsNullOrEmpty(), u => u.Id.ToString() == input.StorageId) on jalc.StorageId equals sg.Id
                        select new
                        {
                            jalc,
                            StyleName = st.StyleName,
                            CartypeName = ct.CartypeName,
                            AlcCodeName = alc.ALCCode,
                            LineCode = ln.LineCode,
                            StorageCode = sg.StorageCode,

                        };

            //var query = from jalc in _jitAlcCodeRepository.GetAll()
            //            join alc in _alcCodeRepository.GetAll() on jalc.AlcCodeId equals alc.Id
            //            join st in _styleRepository.GetAll() on alc.StyleId equals st.Id
            //            join ct in _cartypeRepository.GetAll() on st.CartypeId equals ct.Id
            //            join ln in _lineRepository.GetAll() on jalc.LineId equals ln.Id
            //            join sg in _storageRepository.GetAll() on jalc.StorageId equals sg.Id
            //            select new
            //            {
            //                jalc,
            //                StyleName = st.StyleName,
            //                CartypeName = ct.CartypeName,
            //                AlcCodeName = alc.ALCCode,
            //                LineCode = ln.LineCode,
            //                StorageCode = sg.StorageCode,

            //            };
            //排序
            query = query.OrderBy(x => x.jalc.Id);
            //获取总数
            var tasksCount = query.Count();
            //默认的分页方式
            //ABP提供了扩展方法PageBy分页方式
            var taskList = query.PageBy(input).ToList();

            return new PagedResultDto<JitAlcCodeListDto>(
              tasksCount,
              taskList.Select(item =>
              {
                  var dto = item.jalc.MapTo<JitAlcCodeListDto>();
                  dto.CartypeName = item.CartypeName;
                  dto.StyleName = item.StyleName;
                  dto.AlcCodeName = item.AlcCodeName;
                  dto.LineCode = item.LineCode;
                  dto.StorageCode = item.StorageCode;
                  return dto;
              }).ToList());

            //return new PagedResultDto<AlcCodeListDto>(tasksCount, taskList.MapTo<List<AlcCodeListDto>>());
        }

        /// <summary>
        /// 根据查询条件获取Jit生产ALCCode信息分页列表
        /// </summary>
        public async Task<PagedResultDto<JitAlcCodeListDto>> GetPagedJitAlcCodesAsync(GetJitAlcCodeInput input)
        {

            var query = _jitAlcCodeRepositoryAsNoTrack;
            //TODO:根据传入的参数添加过滤条件

            var jitAlcCodeCount = await query.CountAsync();

            var jitAlcCodes = await query
            .OrderBy(input.Sorting)
            .PageBy(input)
            .ToListAsync();

            var jitAlcCodeListDtos = jitAlcCodes.MapTo<List<JitAlcCodeListDto>>();
            return new PagedResultDto<JitAlcCodeListDto>(
            jitAlcCodeCount,
            jitAlcCodeListDtos
            );
        }

        /// <summary>
        /// 通过Id获取Jit生产ALCCode信息信息进行编辑或修改 
        /// </summary>
        public async Task<GetJitAlcCodeForEditOutput> GetJitAlcCodeForEditAsync(NullableIdDto<int> input)
        {
            var output = new GetJitAlcCodeForEditOutput();

            JitAlcCodeEditDto jitAlcCodeEditDto;

            if (input.Id.HasValue)
            {
                var entity = await _jitAlcCodeRepository.GetAsync(input.Id.Value);
                jitAlcCodeEditDto = entity.MapTo<JitAlcCodeEditDto>();

                output.JitAlcCode = jitAlcCodeEditDto;

                var query = (from jalc in _jitAlcCodeRepository.GetAll()
                             join alc in _alcCodeRepository.GetAll() on jalc.AlcCodeId equals alc.Id
                             join st in _styleRepository.GetAll() on alc.StyleId equals st.Id
                             where (alc.Id == output.JitAlcCode.AlcCodeId)
                             select new
                             {
                                 cartypeId = st.CartypeId,
                                 styleId=alc.StyleId
                             }).ToList();
                output.Cartypes = _cartypeRepository.GetAllList()
                   .Select(c => new ComboboxItemDto(c.Id.ToString(), c.CartypeName) { IsSelected = query.FirstOrDefault().cartypeId == c.Id })
                   .ToList();

                output.Styles = _styleRepository.GetAllList()
                    .Where(c => c.CartypeId == query.FirstOrDefault().cartypeId)
                    .Select(c => new ComboboxItemDto(c.Id.ToString(), c.StyleName) { IsSelected = query.FirstOrDefault().styleId == c.Id })
                    .ToList();

                output.AlcCodes = _alcCodeRepository.GetAllList()
                    .Where(c => c.StyleId == query.FirstOrDefault().styleId)
                    .Select(c => new ComboboxItemDto(c.Id.ToString(), c.ALCCode) { IsSelected = output.JitAlcCode.AlcCodeId == c.Id })
                    .ToList();

                output.Lines = _lineRepository.GetAllList()
                   .Select(c => new ComboboxItemDto(c.Id.ToString(), c.LineCode) { IsSelected = output.JitAlcCode.LineId == c.Id })
                   .ToList();

                output.Storages = _storageRepository.GetAllList()
                   .Select(c => new ComboboxItemDto(c.Id.ToString(), c.StorageCode) { IsSelected = output.JitAlcCode.StorageId == c.Id })
                   .ToList();

            }
            else
            {
                jitAlcCodeEditDto = new JitAlcCodeEditDto();
                output.JitAlcCode = jitAlcCodeEditDto;

                output.Cartypes = _cartypeRepository.GetAllList()
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.CartypeName))
               .ToList();

                output.Styles = _styleRepository.GetAllList()
               //.Where(c => c.CartypeId == int.Parse(output.Cartypes.FirstOrDefault().Value))
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.StyleName))
               .ToList();

                output.AlcCodes = _alcCodeRepository.GetAllList()
               //.Where(c => c.StyleId == int.Parse(output.Styles.FirstOrDefault().Value))
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.ALCCode))
               .ToList();

                output.Lines = _lineRepository.GetAllList()
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.LineCode))
               .ToList();

                output.Storages = _storageRepository.GetAllList()
               .Select(c => new ComboboxItemDto(c.Id.ToString(), c.StorageCode))
               .ToList();

            }

            output.JitAlcCode = jitAlcCodeEditDto;
            return output;
        }


        /// <summary>
        /// 通过指定id获取Jit生产ALCCode信息ListDto信息
        /// </summary>
        public async Task<JitAlcCodeListDto> GetJitAlcCodeByIdAsync(EntityDto<int> input)
        {
            var entity = await _jitAlcCodeRepository.GetAsync(input.Id);

            return entity.MapTo<JitAlcCodeListDto>();
        }







        /// <summary>
        /// 新增或更改Jit生产ALCCode信息
        /// </summary>
        public async Task CreateOrUpdateJitAlcCodeAsync(CreateOrUpdateJitAlcCodeInput input)
        {
            if (input.JitAlcCodeEditDto.Id.HasValue)
            {
                await UpdateJitAlcCodeAsync(input.JitAlcCodeEditDto);
            }
            else
            {
                await CreateJitAlcCodeAsync(input.JitAlcCodeEditDto);
            }
        }

        /// <summary>
        /// 新增Jit生产ALCCode信息
        /// </summary>
        public virtual async Task<JitAlcCodeEditDto> CreateJitAlcCodeAsync(JitAlcCodeEditDto input)
        {
            //TODO:新增前的逻辑判断，是否允许新增

            var entity = input.MapTo<JitAlcCode>();

            entity = await _jitAlcCodeRepository.InsertAsync(entity);
            return entity.MapTo<JitAlcCodeEditDto>();
        }

        /// <summary>
        /// 编辑Jit生产ALCCode信息
        /// </summary>
        public virtual async Task UpdateJitAlcCodeAsync(JitAlcCodeEditDto input)
        {
            //TODO:更新前的逻辑判断，是否允许更新

            var entity = await _jitAlcCodeRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);

            await _jitAlcCodeRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除Jit生产ALCCode信息
        /// </summary>
        public async Task DeleteJitAlcCodeAsync(EntityDto<int> input)
        {
            //TODO:删除前的逻辑判断，是否允许删除
            await _jitAlcCodeRepository.DeleteAsync(input.Id);
        }

        /// <summary>
        /// 批量删除Jit生产ALCCode信息
        /// </summary>
        public async Task BatchDeleteJitAlcCodeAsync(List<int> input)
        {
            //TODO:批量删除前的逻辑判断，是否允许删除
            await _jitAlcCodeRepository.DeleteAsync(s => input.Contains(s.Id));
        }

        #endregion
        #region Jit生产ALCCode信息的Excel导出功能


        public async Task<FileDto> GetJitAlcCodeToExcel()
        {
            var entities = await _jitAlcCodeRepository.GetAll().ToListAsync();

            var dtos = entities.MapTo<List<JitAlcCodeListDto>>();

            var fileDto = _jitAlcCodeListExcelExporter.ExportJitAlcCodeToFile(dtos);



            return fileDto;
        }


        #endregion










    }
}
